package com.yunke.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunke.common.exception.YunkeAssert;
import com.yunke.common.exception.YunkeException;
import com.yunke.common.result.YunkeResult;
import com.yunke.common.result.YunkeResultCode;
import com.yunke.common.security.YunkeSecurityUtil;
import com.yunke.common.util.YunkeTimeUtil;
import com.yunke.dto.service.YunkeServiceBookDto;
import com.yunke.dto.service.YunkeServicePublishDto;
import com.yunke.entity.YunkeService;
import com.yunke.entity.YunkeServiceOrder;
import com.yunke.mapper.YunkeServiceMapper;
import com.yunke.mapper.YunkeServiceOrderMapper;
import com.yunke.service.YunkeServiceService;
import com.yunke.vo.service.YunkeServiceVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 服务Service实现类
 * 
 * @author yunke
 * @since 1.0.0
 */
@Slf4j
@Service
public class YunkeServiceServiceImpl extends ServiceImpl<YunkeServiceMapper, YunkeService> implements YunkeServiceService {

    @Autowired
    private YunkeServiceMapper serviceMapper;

    @Autowired
    private YunkeServiceOrderMapper serviceOrderMapper;

    @Override
    public List<YunkeServiceVo.CategoryInfo> getServiceCategory() {
        log.info("获取服务分类列表");
        
        // TODO: 实现服务分类查询，暂时返回模拟数据
        List<YunkeServiceVo.CategoryInfo> categoryList = new ArrayList<>();
        
        YunkeServiceVo.CategoryInfo category1 = new YunkeServiceVo.CategoryInfo();
        category1.setCategoryId(1L);
        category1.setCategoryName("技术开发");
        category1.setCategoryIcon("icon-tech");
        categoryList.add(category1);
        
        YunkeServiceVo.CategoryInfo category2 = new YunkeServiceVo.CategoryInfo();
        category2.setCategoryId(2L);
        category2.setCategoryName("设计创意");
        category2.setCategoryIcon("icon-design");
        categoryList.add(category2);
        
        YunkeServiceVo.CategoryInfo category3 = new YunkeServiceVo.CategoryInfo();
        category3.setCategoryId(3L);
        category3.setCategoryName("生活服务");
        category3.setCategoryIcon("icon-life");
        categoryList.add(category3);
        
        log.info("获取服务分类列表成功，数量：{}", categoryList.size());
        return categoryList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long publishService(YunkeServicePublishDto publishDto) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("发布服务: userId={}, title={}", userId, publishDto.getTitle());
        
        // 参数验证
        validateServiceParams(publishDto);
        
        // 创建服务对象
        YunkeService service = new YunkeService();
        service.setUserId(userId);
        service.setCategoryId(publishDto.getCategoryId());
        service.setTitle(publishDto.getTitle());
        service.setDescription(publishDto.getDescription());
        service.setCoverImage(publishDto.getCoverImage());
        service.setImages(publishDto.getImages());
        service.setPrice(publishDto.getPrice());
        service.setOriginalPrice(publishDto.getOriginalPrice());
        service.setPriceUnit(publishDto.getPriceUnit());
        service.setServiceType(publishDto.getServiceType());
        service.setServiceArea(publishDto.getServiceArea());
        service.setServiceAddress(publishDto.getServiceAddress());
        service.setLongitude(publishDto.getLongitude());
        service.setLatitude(publishDto.getLatitude());
        service.setDuration(publishDto.getDuration());
        service.setTags(publishDto.getTags());
        service.setContent(publishDto.getContent());
        service.setContact(publishDto.getContact());
        service.setAllowBargain(publishDto.getAllowBargain() == null ? 0 : publishDto.getAllowBargain());
        service.setAllowReservation(publishDto.getAllowReservation() == null ? 1 : publishDto.getAllowReservation());
        
        // 设置默认状态
        service.setStatus(1); // 发布中
        service.setAuditStatus(0); // 待审核
        service.setIsTop(0); // 不置顶
        service.setViewCount(0);
        service.setLikeCount(0);
        service.setFavoriteCount(0);
        service.setOrderCount(0);
        service.setReviewCount(0);
        service.setAvgRating(BigDecimal.valueOf(5.0));
        service.setProviderAuth(0); // TODO: 从用户信息获取认证状态
        service.setWeight(0);
        
        // 设置时间
        long currentTime = System.currentTimeMillis();
        service.setPublishTime(currentTime);
        service.setCreateTime(YunkeTimeUtil.timestampToLocalDateTime(currentTime));
        service.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(currentTime));
        
        // 保存服务
        boolean saveResult = save(service);
        YunkeAssert.isTrue(saveResult, YunkeResultCode.SYSTEM_ERROR, "服务发布失败");
        
        log.info("服务发布成功: serviceId={}", service.getId());
        return service.getId();
    }

    @Override
    public Page<YunkeServiceVo> getServiceList(Long current, Long size, Long categoryId, Integer serviceType, 
                                              String keyword, Integer sortType, Double longitude, Double latitude) {
        log.info("获取服务列表: current={}, size={}, categoryId={}, serviceType={}, keyword={}", 
                current, size, categoryId, serviceType, keyword);
        
        // 构建查询条件
        LambdaQueryWrapper<YunkeService> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YunkeService::getStatus, 1) // 发布中
               .eq(YunkeService::getAuditStatus, 1); // 审核通过
        
        if (categoryId != null) {
            wrapper.eq(YunkeService::getCategoryId, categoryId);
        }
        
        if (serviceType != null) {
            wrapper.eq(YunkeService::getServiceType, serviceType);
        }
        
        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like(YunkeService::getTitle, keyword)
                           .or().like(YunkeService::getDescription, keyword)
                           .or().like(YunkeService::getTags, keyword));
        }
        
        // 排序处理
        handleServiceSort(wrapper, sortType);
        
        // 分页查询
        Page<YunkeService> page = new Page<>(current, size);
        Page<YunkeService> servicePageResult = page(page, wrapper);
        
        // 转换为VO
        Page<YunkeServiceVo> result = new Page<>(current, size);
        result.setTotal(servicePageResult.getTotal());
        
        List<YunkeServiceVo> serviceVoList = new ArrayList<>();
        for (YunkeService service : servicePageResult.getRecords()) {
            YunkeServiceVo serviceVo = convertToServiceVo(service, longitude, latitude);
            serviceVoList.add(serviceVo);
        }
        result.setRecords(serviceVoList);
        
        log.info("获取服务列表成功，数量：{}", serviceVoList.size());
        return result;
    }

    @Override
    public YunkeServiceVo getServiceDetail(Long serviceId) {
        log.info("获取服务详情: serviceId={}", serviceId);
        
        YunkeAssert.notNull(serviceId, YunkeResultCode.PARAM_ERROR, "服务ID不能为空");
        
        YunkeService service = getById(serviceId);
        YunkeAssert.notNull(service, YunkeResultCode.DATA_NOT_EXIST, "服务不存在");
        
        // 增加浏览次数
        service.setViewCount(service.getViewCount() + 1);
        updateById(service);
        
        // 转换为VO
        YunkeServiceVo serviceVo = convertToServiceVo(service, null, null);
        
        log.info("获取服务详情成功: serviceId={}", serviceId);
        return serviceVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long bookService(YunkeServiceBookDto bookDto) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("预订服务: userId={}, serviceId={}", userId, bookDto.getServiceId());
        
        // 查询服务信息
        YunkeService service = getById(bookDto.getServiceId());
        YunkeAssert.notNull(service, YunkeResultCode.DATA_NOT_EXIST, "服务不存在");
        YunkeAssert.isTrue(service.getStatus() == 1, YunkeResultCode.BUSINESS_ERROR, "服务已下架");
        YunkeAssert.isFalse(service.getUserId().equals(userId), YunkeResultCode.BUSINESS_ERROR, "不能预订自己的服务");
        
        // 创建订单
        YunkeServiceOrder order = new YunkeServiceOrder();
        order.setOrderNo(generateOrderNo());
        order.setServiceId(service.getId());
        order.setServiceTitle(service.getTitle());
        order.setProviderId(service.getUserId());
        order.setBuyerId(userId);
        order.setOrderType(bookDto.getOrderType());
        order.setQuantity(bookDto.getQuantity());
        order.setUnitPrice(service.getPrice());
        
        // 计算金额
        BigDecimal totalAmount = service.getPrice().multiply(BigDecimal.valueOf(bookDto.getQuantity()));
        order.setTotalAmount(totalAmount);
        order.setPayAmount(totalAmount);
        order.setDiscountAmount(BigDecimal.ZERO);
        
        // 设置服务信息
        order.setServiceTime(bookDto.getServiceTime());
        order.setServiceAddress(bookDto.getServiceAddress());
        order.setContactName(bookDto.getContactName());
        order.setContactPhone(bookDto.getContactPhone());
        order.setRequirements(bookDto.getRequirements());
        order.setRemark(bookDto.getRemark());
        
        // 设置订单状态
        order.setStatus(1); // 待支付
        order.setPayStatus(0); // 未支付
        order.setIsReviewed(0); // 未评价
        
        // 设置时间
        long currentTime = System.currentTimeMillis();
        order.setCreateTime(YunkeTimeUtil.timestampToLocalDateTime(currentTime));
        order.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(currentTime));
        
        // 保存订单
        boolean saveResult = serviceOrderMapper.insert(order) > 0;
        YunkeAssert.isTrue(saveResult, YunkeResultCode.SYSTEM_ERROR, "订单创建失败");
        
        log.info("预订服务成功: orderId={}", order.getId());
        return order.getId();
    }

    @Override
    public Object payServiceOrder(Long orderId, Integer payMethod, String payPassword) {
        // TODO: 实现支付逻辑
        log.info("订单支付: orderId={}, payMethod={}", orderId, payMethod);
        return "支付功能待实现";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmServiceOrder(Long orderId) {
        // TODO: 实现确认订单逻辑
        log.info("确认服务订单: orderId={}", orderId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeServiceOrder(Long orderId) {
        // TODO: 实现完成订单逻辑
        log.info("完成服务订单: orderId={}", orderId);
        return true;
    }

    @Override
    public Page<YunkeServiceVo> getMyPublishedService(Long current, Long size, Integer status) {
        // TODO: 实现我发布的服务查询
        log.info("获取我发布的服务: current={}, size={}, status={}", current, size, status);
        Page<YunkeServiceVo> result = new Page<>(current, size);
        result.setTotal(0L);
        result.setRecords(new ArrayList<>());
        return result;
    }

    @Override
    public Page<Object> getMyServiceOrder(Long current, Long size, Integer orderType, Integer status) {
        // TODO: 实现我的服务订单查询
        log.info("获取我的服务订单: current={}, size={}, orderType={}, status={}", current, size, orderType, status);
        Page<Object> result = new Page<>(current, size);
        result.setTotal(0L);
        result.setRecords(new ArrayList<>());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reviewService(Long orderId, Double rating, Double serviceRating, Double skillRating, 
                                Double timeRating, Double valueRating, String content, String images, 
                                Boolean isAnonymous, String tags) {
        // TODO: 实现服务评价
        log.info("评价服务: orderId={}, rating={}", orderId, rating);
        return true;
    }

    @Override
    public Page<Object> getServiceReviewList(Long serviceId, Long current, Long size, Integer ratingFilter) {
        // TODO: 实现服务评价列表查询
        log.info("获取服务评价列表: serviceId={}, current={}, size={}, ratingFilter={}", 
                serviceId, current, size, ratingFilter);
        Page<Object> result = new Page<>(current, size);
        result.setTotal(0L);
        result.setRecords(new ArrayList<>());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelServiceOrder(Long orderId, String cancelReason) {
        // TODO: 实现取消订单
        log.info("取消服务订单: orderId={}, cancelReason={}", orderId, cancelReason);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean applyRefund(Long orderId, String refundReason) {
        // TODO: 实现申请退款
        log.info("申请退款: orderId={}, refundReason={}", orderId, refundReason);
        return true;
    }

    /**
     * 验证服务发布参数
     */
    private void validateServiceParams(YunkeServicePublishDto dto) {
        // 验证服务类型和地址
        if (dto.getServiceType() != null && dto.getServiceType() != 1) {
            YunkeAssert.hasText(dto.getServiceArea(), YunkeResultCode.PARAM_ERROR, "线下服务必须填写服务地区");
            YunkeAssert.hasText(dto.getServiceAddress(), YunkeResultCode.PARAM_ERROR, "线下服务必须填写服务地址");
        }
        
        // 验证原价
        if (dto.getOriginalPrice() != null) {
            YunkeAssert.isTrue(dto.getOriginalPrice().compareTo(dto.getPrice()) >= 0, 
                              YunkeResultCode.PARAM_ERROR, "原价不能低于现价");
        }
    }

    /**
     * 处理服务排序
     */
    private void handleServiceSort(LambdaQueryWrapper<YunkeService> wrapper, Integer sortType) {
        if (sortType == null) {
            sortType = 1; // 默认综合排序
        }
        
        switch (sortType) {
            case 1: // 综合排序
                wrapper.orderByDesc(YunkeService::getIsTop)
                       .orderByDesc(YunkeService::getWeight)
                       .orderByDesc(YunkeService::getPublishTime);
                break;
            case 2: // 价格升序
                wrapper.orderByAsc(YunkeService::getPrice);
                break;
            case 3: // 价格降序
                wrapper.orderByDesc(YunkeService::getPrice);
                break;
            case 4: // 评分排序
                wrapper.orderByDesc(YunkeService::getAvgRating)
                       .orderByDesc(YunkeService::getReviewCount);
                break;
            case 5: // 距离排序（需要经纬度）
                wrapper.orderByDesc(YunkeService::getPublishTime);
                break;
            default:
                wrapper.orderByDesc(YunkeService::getPublishTime);
        }
    }

    /**
     * 转换为服务VO
     */
    private YunkeServiceVo convertToServiceVo(YunkeService service, Double longitude, Double latitude) {
        YunkeServiceVo vo = new YunkeServiceVo();
        
        // 基本信息
        vo.setId(service.getId());
        vo.setTitle(service.getTitle());
        vo.setDescription(service.getDescription());
        vo.setCoverImage(service.getCoverImage());
        
        // 图片列表
        if (StringUtils.hasText(service.getImages())) {
            vo.setImageList(Arrays.asList(service.getImages().split(",")));
        }
        
        // 价格信息
        vo.setPrice(service.getPrice());
        vo.setOriginalPrice(service.getOriginalPrice());
        vo.setPriceUnitText(getPriceUnitText(service.getPriceUnit()));
        
        // 服务信息
        vo.setServiceTypeText(getServiceTypeText(service.getServiceType()));
        vo.setServiceArea(service.getServiceArea());
        vo.setServiceAddress(service.getServiceAddress());
        vo.setLongitude(service.getLongitude());
        vo.setLatitude(service.getLatitude());
        vo.setDuration(service.getDuration());
        vo.setDurationText(getDurationText(service.getDuration()));
        
        // 标签列表
        if (StringUtils.hasText(service.getTags())) {
            vo.setTagList(Arrays.asList(service.getTags().split(",")));
        }
        
        vo.setContent(service.getContent());
        vo.setContact(service.getContact());
        
        // 状态信息
        vo.setStatusText(getStatusText(service.getStatus()));
        vo.setAuditStatusText(getAuditStatusText(service.getAuditStatus()));
        vo.setIsTop(service.getIsTop() == 1);
        
        // 统计信息
        vo.setViewCount(service.getViewCount());
        vo.setLikeCount(service.getLikeCount());
        vo.setFavoriteCount(service.getFavoriteCount());
        vo.setOrderCount(service.getOrderCount());
        vo.setReviewCount(service.getReviewCount());
        vo.setAvgRating(service.getAvgRating());
        
        // 服务提供者信息
        vo.setProviderAuthText(getProviderAuthText(service.getProviderAuth()));
        vo.setAllowBargain(service.getAllowBargain() == 1);
        vo.setAllowReservation(service.getAllowReservation() == 1);
        
        // 时间信息
        vo.setPublishTime(service.getPublishTime());
        vo.setPublishTimeText(formatTime(service.getPublishTime()));
        
        // TODO: 设置用户信息、分类信息、距离信息、是否点赞收藏等
        
        return vo;
    }

    /**
     * 获取价格单位文本
     */
    private String getPriceUnitText(Integer priceUnit) {
        if (priceUnit == null) return "";
        switch (priceUnit) {
            case 1: return "次";
            case 2: return "小时";
            case 3: return "天";
            case 4: return "月";
            case 5: return "年";
            default: return "";
        }
    }

    /**
     * 获取服务类型文本
     */
    private String getServiceTypeText(Integer serviceType) {
        if (serviceType == null) return "";
        switch (serviceType) {
            case 1: return "线上服务";
            case 2: return "线下服务";
            case 3: return "上门服务";
            default: return "";
        }
    }

    /**
     * 获取时长文本
     */
    private String getDurationText(Integer duration) {
        if (duration == null || duration <= 0) return "";
        if (duration < 60) {
            return duration + "分钟";
        } else if (duration < 1440) {
            return (duration / 60) + "小时" + (duration % 60 > 0 ? (duration % 60) + "分钟" : "");
        } else {
            int days = duration / 1440;
            int hours = (duration % 1440) / 60;
            return days + "天" + (hours > 0 ? hours + "小时" : "");
        }
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        if (status == null) return "";
        switch (status) {
            case 1: return "发布中";
            case 2: return "暂停接单";
            case 3: return "已下架";
            case 4: return "已删除";
            default: return "";
        }
    }

    /**
     * 获取审核状态文本
     */
    private String getAuditStatusText(Integer auditStatus) {
        if (auditStatus == null) return "";
        switch (auditStatus) {
            case 0: return "待审核";
            case 1: return "审核通过";
            case 2: return "审核拒绝";
            default: return "";
        }
    }

    /**
     * 获取认证状态文本
     */
    private String getProviderAuthText(Integer providerAuth) {
        if (providerAuth == null) return "";
        switch (providerAuth) {
            case 0: return "未认证";
            case 1: return "个人认证";
            case 2: return "企业认证";
            default: return "";
        }
    }

    /**
     * 格式化时间
     */
    private String formatTime(Long timestamp) {
        if (timestamp == null) return "";
        
        long now = System.currentTimeMillis();
        long diff = now - timestamp;
        
        if (diff < 60000) { // 1分钟内
            return "刚刚";
        } else if (diff < 3600000) { // 1小时内
            return (diff / 60000) + "分钟前";
        } else if (diff < 86400000) { // 24小时内
            return (diff / 3600000) + "小时前";
        } else if (diff < 2592000000L) { // 30天内
            return (diff / 86400000) + "天前";
        } else {
            return "很久之前";
        }
    }

    /**
     * 生成订单编号
     */
    private String generateOrderNo() {
        return "SRV" + System.currentTimeMillis() + 
               String.format("%04d", (int)(Math.random() * 10000));
    }
} 